版本控制:AI 时代的安全网
你会学到什么
上一节用 AI 搭建了项目骨架。在让 AI 开始写代码之前,有一件事必须先搞明白——版本控制。本节不讲 Git 基础(你都会),聚焦三件事:AI 时代为什么要更重视版本控制、用什么工具看 diff、以及一个标准的 AI 协作工作流。
学完后,你知道 AI 改完代码后用什么工具查看变更、怎么看、怎么回退,形成一套"AI 改代码 → 你看 diff → 确认提交"的标准流程。
AI 时代版本控制为什么更重要
传统开发中,版本控制的价值是"方便回退"和"多人协作"。AI 时代多了一个更重要的价值:防止 AI 的过激行为。
AI 会"过度修改"
让 AI 改一个 Button 的颜色,它可能顺手把整个组件重构成另一种写法。你看了一眼"颜色确实改对了",就提交了——但组件的行为可能已经变了。
# 你说
> 把 Button 的主题色从蓝色改成红色
# AI 可能做了
✓ 修改了主题色 ← 你要求的
✓ 重构了组件为 Composition API ← 你没要求
✓ 改了 props 的类型定义 ← 你没要求
✓ 删了几个"没用"的方法 ← 其实其他地方在用
text
AI 会"误删代码"
AI 认为某段代码"没有用到",就删了。但那段代码可能是通过动态字符串调用的(路由配置、插件注册),AI 的静态分析发现不了。
AI 会"幻觉依赖"
AI 可能引用一个不存在的 API 或已废弃的库方法。本地测试没覆盖到这个路径,线上才出问题。
工具自带的 restore 救不了你
有同学会说:很多 AI 工具不是有 restore / undo 功能吗?注意它的两个局限:restore 只在当前会话窗口内有效;一旦 AI 改了很多文件、上下文窗口丢掉了一部分信息,undo 基本回撤不回去。所以会话内的 restore 只能当临时后悔药,本地文件的可靠管理必须交给版本控制。
核心结论
| 场景 | 没有版本控制 | 有版本控制 |
|---|---|---|
| AI 过度修改 | 不知道改了什么 | diff 一眼看清 |
| AI 误删代码 | 代码丢了找不回来 | 一键恢复 |
| AI 引入 bug | 不确定是哪个改动引起的 | 精确定位回退 |
| AI 改了不该改的文件 | 无法部分撤回 | 恢复单个文件 |
版本控制是 AI 编程时代最重要的安全机制。
用什么工具看 diff
这是本节的重点。AI 改完代码后,你必须看 diff 确认它做了什么。以下是从终端到编辑器到 AI 的全部工具:
终端命令(最快)
# 看改了哪些文件(先看这个,快速判断 AI 改了多少东西)
git diff --stat
# Button.vue | 12 ++++----
# theme.css | 8 ++++-
# utils.ts | 45 ++++++++++++++++++++++++++ ← 45行?!AI改了utils?
# 看具体改了什么(逐行对比)
git diff
# 只看某个文件的改动
git diff src/components/Button.vue
# 看已暂存的改动(git add 之后)
git diff --cached
bash
git diff 的阅读方式:绿色行 + 是新增,红色行 - 是删除。重点看红色行——AI 删了什么往往比你想象的更重要。
VS Code 内置 Git(最直观)
VS Code 左侧栏的 Source Control 面板就是你最常用的 diff 工具。注意一个前提:需要先初始化 Git 仓库才能看到文件差异(下文"初始化仓库"会讲)。
1. 点击左侧 Source Control 图标(分支形状)
2. 看到变更文件列表 → 每个文件旁边的字母标识变更类型:
U = 未跟踪 M = 已修改 A = 已添加 D = 已删除
3. 点击任意文件 → 打开并排对比视图:
左边是改之前的代码,右边是改之后的代码
删除的行红色背景,新增的行绿色背景(和终端 git diff 红减绿加一致)
4. 如果某个改动不对 → 点击行号左侧的"撤销"箭头,恢复这行
5. 变更文件太多不好看 → 面板右上角"..."菜单 → View Changes / 以树形式查看,
按目录层级折叠展示,一眼看清 AI 动了哪些模块
text
再装三个插件,体验完整一个档次:
| 插件 | 作用 |
|---|---|
| GitLens | 行内 blame、文件历史、谁在什么时候改的这行 |
| Git Graph | 可视化提交图谱,分支合并关系一目了然 |
| .gitignore | 右键一键把文件/目录加入 .gitignore |
其中 .gitignore 插件解决的痛点很实际:测试文件、备份文件、.env 这类私密的环境变量文件,都不该进版本库——右键忽略比手写规则快得多。
VS Code diff 的优势:并排对比比终端的 git diff 直观得多,尤其看 HTML/Vue 模板的改动。点击文件就能看,不需要记命令。Cursor、Windsurf 这类基于 VS Code 二开的编辑器同样能装这些插件。
Cursor 内置 Git
Cursor 的版本控制跟 VS Code 一样(左侧 Source Control 面板),但多了一个 AI 能力——在 Chat 中输入 @Git 引用代码变更让 AI 分析:
# 在 Cursor Chat 中输入 @,选择 Git,再选择:
@Git → @Commit # 对比上次 commit,看未提交的改动(AI 刚改完代码时用这个)
@Git → @Branch # 对比 main 分支,看当前分支所有已提交的改动
# 示例
@Git 这次的改动有什么潜在问题?
text
@Commit 显示未提交的改动(新增、修改、删除的文件),@Branch 显示当前分支相对于 main 的所有变更。等于"AI 帮你看 AI 的改动"——第二双眼睛。
其他 GUI 工具
| 工具 | 平台 | 特点 | 费用 |
|---|---|---|---|
| GitHub Desktop | Win/Mac | 最简单,适合看 diff 和提交 | 免费 |
| GitKraken | Win/Mac/Linux | 可视化分支图,merge 冲突解决好 | 免费/Pro $4.95/月 |
| Sourcetree | Win/Mac | Atlassian 出品,功能全 | 免费 |
| lazygit | 终端 | 终端内的 Git GUI,vim 风格 | 免费 |
| TortoiseGit | Windows | 右键菜单集成 | 免费 |
推荐:VS Code / Cursor 的 Source Control 面板已经够用。如果经常处理复杂合并,GitKraken 的可视化分支图很有帮助。lazygit 适合终端党。
让 AI 帮你看 diff
AI 改完代码后,你可以直接让 Claude Code 解释变更:
> 请总结当前的代码变更,指出哪些是我没要求的改动
AI 会分析 git diff 并返回:
- 你要求的改动:Button.vue 主题色修改 ✓
- 你没要求的改动:utils.ts 新增了 formatTheme 函数(与本次需求无关)
- 潜在问题:删除了 handleClick 方法,但 Sidebar.vue 中有引用
text
这是 AI 时代特有的优势——让 AI 自己解释它改了什么,帮你快速发现过激行为。
AI 还能做历史溯源——这是版本库给 AI 的反向加成。只要文件提交过,AI 就能快速翻出它或一系列文件的历史提交:
# 追问文档演进
> 哪个版本改了这个 README?现在的 README 是否涵盖了所有项目历史提交的信息?
# 看不懂某段代码时,问它的来龙去脉
> 这个文件是什么时候创建的?经历了哪几个版本?和哪些文件有关联?
> 总结一下这个功能从最初版本到现在的发展历程。
text
AI 会搜出与这个功能相关联的所有提交,甚至总结出功能从简单到复杂的演进史。以前要懂 git log --follow、git blame 才能干的事,现在一句自然语言搞定。
初始化仓库:两分钟的事
还没初始化仓库?先装 Git:到 git-scm.com 选平台下载,macOS 直接 brew install git(或用 App Store 的 Xcode 命令行工具),Windows 下载安装包一路默认即可。
装完之后你不需要记命令,两种方式二选一:
# 方式一:自己敲一条
git init
bash
# 方式二:让 AI 全权代办(推荐)
> 在当前目录初始化一个 git 仓库,并提交一个初始版本
text
让 AI 代办的额外好处:它会顺手把 .gitignore 配好——node_modules/、dist/、macOS 的 .DS_Store 这类不该进版本库的文件全部排除,然后一次性提交几十个文件作为初始版本。提交之后还有一个隐性收益:AI 自己也能快速溯源任何文件的历史,上面的历史溯源能力从此可用。后续的分支、合并、日志等操作,可以直接用 superpowers 等 Skill 合集里与 Git 相关的技能完成。
标准工作流:AI 改代码 → 你看 diff → 确认提交
把上面这些工具串起来,就是一个标准的 AI 协作版本控制工作流:
第1步:改之前确保工作区干净
先说清楚"工作区":仓库初始化之后,你任意修改一个文件,Source Control 面板立刻追踪到更改——这些未被提交的变更所在的状态就是工作区。平时保持工作区干净(没有未提交的改动)是一个核心习惯,这样 git diff 显示的永远只是 AI 这一次的改动,不会和之前的变更混在一起。
> 是否完成了特定功能的开发?已完成请提交代码
text
平时不用这么啰嗦,直接装上 Claude Code 官方插件市场(claude-code-plugins,默认安装)提供的 commit 插件,之后一句 /commit 即可完成提交与日志——第3节会详细讲它。
第2步:让 AI 改代码
> 把 Button 主题色改成红色,只改颜色相关的代码
text
提示词里加"只改xxx相关的代码",约束 AI 的行为范围。
第3步:看 diff(关键步骤!)
# 方式一:终端快速扫描
git diff --stat # 看改了哪些文件
# 方式二:VS Code / Cursor 逐文件查看
# 点击 Source Control 面板,逐个文件看并排对比
# 方式三:让 AI 解释变更
> 请总结当前的代码变更,指出哪些是我没要求的改动
text
三种方式选一种,但这一步不能跳过。
第4步:处理不想要的改动
# AI 改了不该改的文件 → 恢复整个文件
git checkout -- src/utils/validator.ts
# 只想保留部分改动 → 交互式选择
git add -p # 逐块确认要暂存的改动
# VS Code 里更直观 → 在 diff 视图点击行号左侧的撤销箭头
bash
第5步:确认后提交
> 提交代码
text
AI 生成 commit message,你审查确认。
完整流程一图流
确保工作区干净 → 让 AI 改代码 → 看 diff → 处理不想要的改动 → 提交
↑ ↓
└────── 不满意直接 git checkout 恢复 ←──────────┘
text
用自然语言做版本控制
有了 AI,大部分 Git 操作不再需要记命令——用自然语言描述你想做什么:
分支操作
> 请基于最新的 main 创建 feature/button-loading 分支并切换过去
> 列出所有本地分支
> 切换回 main 分支
> 删除 feature/button-color 分支
text
Claude Code 自动执行对应的 Git 命令。你不需要记 git checkout -b、git branch -D 这些参数。
查看变更
> 当前的代码变更概要是什么?
> Button.vue 这个文件具体改了什么?
> 这次改动和 main 分支有什么区别?
text
AI 直接用自然语言总结 diff,比你自己看 git diff 输出更高效。
回退操作
> 上一次提交有问题,帮我撤销那个提交(保留改动在工作区)
> 把 src/utils/validator.ts 恢复到上一次提交的状态
> 我要回到 v1.2.0 那个版本看看代码
text
# 传统方式你需要知道
git reset --soft HEAD~1 # 撤销提交保留改动
git checkout HEAD -- src/utils/validator.ts # 恢复单个文件
git checkout v1.2.0 # 切到某个版本
# AI 方式你只需要说
> 撤销上一次提交,但保留改动
> 恢复 validator.ts 到上次提交
> 回到 v1.2.0 看看
text
PR 和 Code Review
> 为当前分支创建 PR
> 审查当前分支的代码变更,关注安全漏洞和性能问题
> 合并 main 到当前分支,有冲突帮我解决
text
AI 会自动生成 PR 描述、做第一轮 Code Review、辅助解决合并冲突。
对比:传统 vs 自然语言
| 操作 | 传统命令 | 自然语言 |
|---|---|---|
| 创建分支 | git checkout -b feature/xxx | "创建 feature/xxx 分支" |
| 查看 diff | git diff --stat | "当前变更概要是什么" |
| 恢复文件 | git checkout -- file.ts | "恢复 file.ts" |
| 撤销提交 | git reset --soft HEAD~1 | "撤销上次提交保留改动" |
| 创建 PR | gh pr create --title ... --body ... | "为当前分支创建 PR" |
你不再需要记 Git 命令,只需要描述意图。 但有一个前提:你得知道"我想做什么"。Git 命令背后的概念(分支、暂存、回退)仍然需要理解,只是具体的命令参数可以交给 AI。
分支策略:GitHub Flow 够用
没接触过分支的同学可以把它想象成树杈:一棵树有很多分支,开发到某个节点,一件事还没做完、又不想影响另一件事,就出现分岔路口——从当前节点拉一条新分支各干各的,做完再合并回来。分支解决的就是"并行推进、互不干扰",具体概念细节可以直接问 AI,这里不展开。
main(生产代码,永远可部署)
│
├── feature/button-theme ← 功能分支(新特性)
├── fix/input-validation ← 修复分支(修 bug)
├── docs/api-reference ← 文档分支(文档更新)
└── refactor/table-sort ← 重构分支(非破坏性重构)
text
前端项目推荐 GitHub Flow——简单直接。除非组件库需要维护多个大版本,否则不需要 Git Flow。
分支命名写在 CLAUDE.md 里,AI 自动遵循:
## Git 工作流规范
- 分支命名:feature/xxx、fix/xxx、docs/xxx、refactor/xxx
- 每个功能一个分支,做完一个再做下一个
- 合并后立即删除分支
markdown
个人项目的务实建议:分支管理不必严格遵循,把重点放在三件事上——查看变更、恢复文件、撤销更改。有版本库兜底 + CLAUDE.md 约束写清楚,单人开发基本不会出事。
团队实战:GitHub 上的完整质量协作流
个人项目到上面就够用了。但如果是一个团队,还要在 GitHub 上做 Issue 讨论、计划规划、PR 合并——这些操作建立在你熟悉上面的 Git 工作流之上。下面是一场完整的实战演示:从建仓到 AI 自动完成 PR 全流程。
第一步:准备凭据(Token + Deploy Key)
在 GitHub 新建一个仓库(如 learn-ai),然后配置两样东西:
Fine-grained Personal Access Token(Settings → Developer settings → Personal access tokens → Fine-grained tokens):点 Generate new token,设置名称、过期时间(测试用 7 天,长期可选 No expiration)、作用范围(All repositories),然后勾权限。常用权限清单:
| 权限 | 用途 | 建议 |
|---|---|---|
| Contents | 读写代码 | Read and write |
| Issues | 创建/读取 Issue | Read and write |
| Pull requests | 创建/合并 PR | Read and write |
| Actions | 触发/读取 CI | Read and write |
| Deployments / Environments | 部署 | Read and write |
| Pages | GitHub Pages 部署 | Read and write |
| Secrets / Variables / Webhooks / Workflows | CI 配置与流水线 | Read and write |
| Merge queue / Discussions / Artifacts | 合队列、讨论、制品 | 按需 |
权限每项都有 Read-only 和 Read and write 两档,按需放开即可。
Deploy Key(仓库 Settings → Deploy keys):用于把代码部署/推送到这个仓库,添加时勾选写权限。
第二步:一句话让 AI 配好本地凭据
在项目目录新开一个 Claude Code 会话:
这是我的 GitHub 高权限 token:ghp_xxx,记忆到本项目的 .env 中方便后续使用。
创建一个本项目专用的 SSH key(名称为 ai),把公钥发给我,我需要配置到 GitHub 的 Deploy Key 里。
text
AI 会全自动完成:创建 .env 环境文件记录 token → 生成专用 SSH key(会先问你是否复用现有 key,选择新建专用)→ 输出公钥。你把公钥复制到 GitHub 的 Deploy Key 页面(注意去掉换行、勾选写权限),然后补一条配置:
仓库地址是 git@github.com:yourname/learn-ai.git,配置 remote,
提交用户名是 brian、邮箱是 brian@example.com,只在本项目生效,不要全局配置
text
AI 会写好 ~/.ssh/config、配置 remote 与提交者信息,并确认 .gitignore 已排除 .env——敏感信息绝不能推到远端,否则任何能访问仓库的人都能拿到它。
第三步:推送代码 + 生成开发计划 Issue
推送本地的代码到远端,并在 GitHub Issues 中创建一份组件库开发计划(plan)
text
你从头到尾没告诉它怎么连 GitHub、用什么命令——AI 自己完成提交(配置了 Git Hooks 的话 lint-staged 会自动先跑检查)、生成一条 Conventional Commits 格式的提交信息、push、再调 GitHub API 创建开发计划 Issue。刷新仓库页面,Issue 里已经有分阶段、分组件的完整开发计划。
第四步:新成员/新窗口对齐进度
换个新窗口(模拟另一位协作者拿到仓库):
获取最新的 Issues,并读取本地项目的代码状态,告诉我还有哪些未完成待开发的功能
text
前提是这个会话也配好了有 Issues 读权限的 token 和 Deploy Key。AI 会拉取全部 Issue、读取本地代码逐一对比,输出一张"计划 vs 现状"的进度表——晨会对齐进度这一步也省了。
第五步:把团队工作流固化进 CLAUDE.md
最关键的一步,让 AI 自己把协作规范写进项目约束:
我想使用最新的 GitHub 分支管理规范来引导开发:
功能开发完成后,检查 GitHub Issues 并完成对应的提交;
之后在远端 GitHub 创建对应的 PR 并编写 PR 描述。
把以上协作规则写入 CLAUDE.md
text
AI 会生成一段"AI 协作职责",典型内容:
## AI 协作职责(GitHub 工作流)
- 开发前:读取项目 Issues,确认当前要做的任务
- 开发中:在功能分支上提交,不直接提交到 master/main
- 开发后:推送功能分支到远端,编写变更摘要,创建 PR 并关联对应 Issue
- 合并后:删除远端功能分支,本地切回 main 并拉取最新代码
markdown
然后验证整套流程:
请开发一个示例的 Button 组件,并完整演示上面的 PR 流程
text
你会看到 AI:读取 Issue 确认任务 → 创建 feature 分支 → 写组件代码(期间 ESLint 报错会被动触发自动修复——这就是第4节配的质量工具在兜底)→ 提交 → 推送 → 创建带 summary、commits、文件变更、test plan 的 PR → 等待合并。甚至代码审核也可以交给 AI:让它拉取最近的 PR、审核代码、本地跑测试评估,最后合并。
角色分工
| 角色 | 职责 |
|---|---|
| 开发者 | 创建 Issue、创建开发分支、完成开发与提交、创建 PR |
| 审核者(管理者) | 拉取 PR 代码、读取 PR 摘要、本地验证功能、检查是否缺测试、合并 |
在提示词里声明你的角色(开发者 / 产品经理 / 项目经理),AI 生成的协作流程会随角色变化——同一个仓库,不同角色问出不同的工作流。
事前约束:在 CLAUDE.md 中限制 AI 行为
版本控制是事后检查。更好的做法是事前约束 AI:
## 代码修改规范
- 不要删除你不确定是否使用的代码,先标记 TODO
- 不要重构你没有被要求重构的代码
- 不要修改你不直接相关的文件
- 每次改动只做被要求的事,不多不少
- 修改前先阅读相关文件,理解上下文
markdown
这种约束不能100%防止过激行为,但能大幅降低概率。配合 diff 检查,形成事前约束 + 事后检查的双重保护。
本节要点
- AI 时代版本控制的核心价值是防止 AI 搞砸:过度修改、误删代码、幻觉依赖;工具自带的 restore 只在当前会话有效,救不了多文件大改动
- 看 diff 是关键操作:终端
git diff快速扫描、VS Code 并排对比最直观(配 GitLens/Git Graph/.gitignore 三插件)、让 AI 解释 diff 最高效 - 标准工作流五步:确保工作区干净 → AI 改代码 → 看 diff → 处理不想要的改动 → 确认提交;
/commit命令来自官方插件市场 - 自然语言做版本控制:描述意图就行(分支、历史溯源、回退、冲突合并),不需要记 Git 命令参数,但背后的概念(工作区、分支、快照)仍需理解
- 团队协作流:Fine-grained Token + Deploy Key 配好后,AI 能完成推送、创建计划 Issue、进度对齐、按 CLAUDE.md 里的协作职责走完 Issue → feature 分支 → PR → 合并的全流程
- 事前约束 + 事后检查:CLAUDE.md 约束 AI 行为(事前),diff 工具检查改动(事后)
下一节讲代码自动提交——有了版本控制的基础,让 AI 帮你生成规范的 commit message。
↑